#include "StdAfx.h"
//-------------------------------------------------------------------------------------------------
//OspacsDb.h  - Implementation of OspacsDb, concrete Implementation of APDatabase for actual database access          
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2011 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk Feb 2011
//
//----Comments-------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------

#include <iostream>
#include <string>
#include <vector>

#include "ImageRec.h"
#include "ImageData.h"
#include "UraDb.h"


UraDb::UraDb(void)
{
	_ImageRecord = new CImageRec;
	_HrError = 0L;
}


UraDb::~UraDb(void)
{
	ClearImages();

	delete _ImageRecord;
	
}

const TCHAR *UraDb::GetErrorMsg()
{
	if ( HRESULT_CODE(_HrError) == UraDb::MaxRecordsReturned )
		return L"More records returned than allowed by program";
	else
	{
		return _com_error(_HrError).ErrorMessage();
	}
}

LPCOLESTR UraDb::GetConnectStr(TCHAR *DbConnectionLabel) 
{ 
	LPOLESTR rc = '\0';

	HKEY hk; 
    long n = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\UCL-IfWH\\ArchiveProcGUI\\Database\\"), 0, KEY_QUERY_VALUE, &hk ); 
    if ( n == ERROR_SUCCESS ) 
	{ 
		DWORD val = 490;
		if ( RegQueryValueEx(hk, DbConnectionLabel, NULL, NULL, (LPBYTE)_buffer, &val) == ERROR_SUCCESS)
		{
			rc = W2OLE((wchar_t*)_buffer);
		}
    } 
	return rc; 
}


void UraDb::ClearImages()
{
	ImageData *p;
	std::vector<ImageData *>::iterator iter = _Images.begin();
	while( iter != _Images.end() ) 
	{
		p = *iter;
		delete *iter;
		++iter;
	}
	_Images.clear();
}

bool UraDb::OpenSession(LPCOLESTR connectStr)
{
	bool rc = false;

	if  (connectStr != '\0')
	{
		CDataSource _db;

		_HrError = _db.OpenFromInitializationString(connectStr);
		if (FAILED(_HrError))
		{
	#ifdef _DEBUG
			AtlTraceErrorRecords(_HrError);
	#endif
		}
		else
		{
			_HrError = _ImageRecord->m_session.Open(_db);
			if (FAILED(_HrError))
			{
		#ifdef _DEBUG
				AtlTraceErrorRecords(_HrError);
		#endif
			}
			else
			{
				rc = true;
			}
		}
	}
	return rc;
}

bool UraDb::OpenDbSession(TCHAR *DbConnectionLabel)
{
	bool rc = false;

	rc = OpenSession(GetConnectStr(DbConnectionLabel));  

	return rc;
}

void  UraDb::CloseDbSession()
{
	_ImageRecord->m_session.Close();
}

bool  UraDb::GetRecords(LPCOLESTR SqlQuery, int maxRecords)
{
	using std::cout;
	using std::wcout;
	using std::endl;

	bool rc = false;

	ClearImages();
	_Images.reserve(maxRecords);

	CDBPropSet propset(DBPROPSET_ROWSET);
	_ImageRecord->GetRowsetProperties(&propset);

	_HrError = _ImageRecord->Open(_ImageRecord->m_session, SqlQuery, &propset);

	if(FAILED(_HrError))
	{
#ifdef _DEBUG
		AtlTraceErrorRecords(_HrError);
#endif
	}
	else
	{
		_HrError = _ImageRecord->MoveFirst(); 

		if(FAILED(_HrError))
		{
#ifdef _DEBUG
			AtlTraceErrorRecords(_HrError);
#endif
		}
		else
		{
			for (int x = 0; x < maxRecords; x++ )
			{
				if ( _HrError == DB_S_ENDOFROWSET )
				{
					rc = true;
					break;
				}
				ImageData *pImage = new ImageData();

				if ( _ImageRecord->m_dwDicomFileStatus != DBSTATUS_S_OK ) 
					pImage->SetErrorCode(_ImageRecord->m_dwDicomFileStatus);
				else
				{
					pImage->SetStoredBy(_ImageRecord->m_StoredBy);
	
					if ( _ImageRecord->m_DicomFileSize != _ImageRecord->m_dwDicomFileLength )
						pImage->SetErrorCode((DBSTATUS) ImageData::LengthMismatch);
					else
					{
						if ( ! pImage->GetDicomFile()->SetData(_ImageRecord->m_DicomRef, _ImageRecord->m_DicomFile, _ImageRecord->m_dwDicomFileLength))
							pImage->SetErrorCode((DBSTATUS) ImageData::DicomError);
						else
						{
							if (! pImage->SetBitMap(pImage->GetDicomFile()->CreateBitMap()))
								pImage->SetErrorCode((DBSTATUS) ImageData::BitMapCreateError);
						}
					}
				}
				_Images.push_back(pImage);

				_HrError = _ImageRecord->MoveNext();
				if(FAILED(_HrError))
				{
#ifdef _DEBUG
						AtlTraceErrorRecords(_HrError);
#endif
				}
			}
			if ( rc != true )
			{
				 _HrError = MAKE_HRESULT(true,FACILITY_NULL,UraDb::MaxRecordsReturned);
			}
		}
		_ImageRecord->Close();
	}
	return rc;
}

//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------